package com.ossean.util;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ossean.databaseDest.DBDest;
import com.ossean.databaseSource.DBSource;
import com.ossean.databaseSource.GatherDao;
import com.ossean.databaseSource.PKControlProjectsDao;
import com.ossean.databaseSource.UpdateControlProjectsDao;
import com.ossean.model.Configure;
import com.ossean.model.EddRelations;
import com.ossean.model.GatherProjectsModel;
import com.ossean.model.PKControlProjects;
import com.ossean.model.Taggings;
import com.ossean.model.UpdateControlProjects;

@Component("gatherProjectsUtil")
public class GatherProjectsUtil {
	Logger logger = Logger.getLogger(this.getClass());
	
	@Resource
	private DBSource dbSource;
	@Resource
	private DBDest dbDest;
	@Resource
	private GatherDao gatherDao;
	@Resource
	private PKControlProjectsDao pkControlProjectsDao;
	@Resource
	private UpdateControlProjectsDao updateControlProjectsDao;
	
	private String gatherProjectsTableName = "gather_projects";
	
	private String taggingsTableName = "edd_taggings";
	private String tagsTableName = "edd_tags";
	
	
	private String pkControlProjectsTableName = "pk_control_projects";
	private String updateControlProjectsTableName = "update_control_projects";
	
	
	//批量处理转移数据 需要处理为原子操作
	@Transactional(propagation=Propagation.REQUIRED)
	public void handleBatchData(Map checkDoneMap, Configure conf){
		logger.info("BeginId#"+conf.getSourceTableName()+":"+ checkDoneMap.get("BeginId"));
        int sourceIdBegin = Integer.parseInt(checkDoneMap.get("BeginId").toString());
        int sourceIdEnd = Integer.parseInt(checkDoneMap.get("EndId").toString());
        
        if (checkDoneMap.get("EndTime") == null) {
        	//表示任务没有完成
            int maxId = dbSource.getMaxId(conf.getSourceTableName());

            // 防止转移超过当前最大值的Id数据
            if (sourceIdBegin >= 0 && sourceIdEnd > 0 && maxId >= sourceIdEnd) {
                // 更新执行开始时间
                gatherDao.updateTaskBeginTime(conf.getMigrationTask(),sourceIdBegin,conf.getSourceTableName(),conf.getTargetTableName());
                logger.info("Transaction...@"+ new Date());
                // 插入Id段数据，忽略重复值
                int num = 0;
                try {
                    String[] sourceFields=conf.getSourceFields().split(",");
                    String[] targetFields = conf.getTargetFields().split(",");
                    String selectItems = "";
                    for(int i = 0; i < sourceFields.length; i++){
                    	String str_source = sourceFields[i];
                    	String str_target = targetFields[i];
                    	selectItems += str_source + " as " + str_target + ",";
                    }
                    selectItems = selectItems.substring(0, selectItems.length() - 1) + " ";
                    List<GatherProjectsModel> dataGet = gatherDao.moveDataGet(
                            conf.getSourceTableName(),selectItems,
                            sourceIdBegin,sourceIdEnd,conf.getAndWhere());

                    num = dataGet.size();
                    for(int i = 0; i < dataGet.size(); i++){
                    	GatherProjectsModel model = dataGet.get(i);
                    	String urlMD5 = model.getUrl_md5();//通过urlMD5判断是不是已经存在过该项目 是否更新
                    	GatherProjectsModel sameProject = gatherDao.selectGPMByUrlMD5(conf.getTargetTableName(), urlMD5);
                    	if(sameProject == null){
                    		//不存在 插入
                    		PKControlProjects pkControlModel = pkControlProjectsDao.selectItemByUrlMD5(pkControlProjectsTableName, urlMD5);//查看有没有固定的id
                    		if(pkControlModel != null)
                    			model.setId(pkControlModel.getId());
                    		else{
                    			//在pk_control_projects表中生成当前项目对应的id
                        		pkControlProjectsDao.insertOneItem(pkControlProjectsTableName, urlMD5);
                        		//查看刚刚插入信息的id
                        		PKControlProjects controlItem = pkControlProjectsDao.selectItemByUrlMD5(pkControlProjectsTableName, urlMD5);
                        		//用id构造model对应的固定不变的id
                        		model.setId(controlItem.getId());
                    		}
                    		handleInsertGatherProjects(model, conf);
                    	}else{
                    		//update gather_projects表中对应的记录，在维持待更新表
                    		handleUpdateGatherProjects(sameProject.getId(),model);
                    	}
                    	
                    	//将tag和项目的关系存入表item_tag_relation 并分离tag
                    	String tags = model.getTags();
                    	if(tags == null){
                    		//表示该项目没有标签
                    		continue;
                    	}
                    	String[] tagArray = tags.split(",");
                    	for(String tag:tagArray){
                    		tag = tag.substring(1, tag.length() - 1).toLowerCase();//去掉两边的尖括号 并转换为小写
                    		gatherDao.insertTag(tagsTableName, tag);//ignore方式插入该项目的标签
                    		int tag_id = gatherDao.selectTagIdByName(tagsTableName, tag);
                    		Taggings taggings = new Taggings();
                    		taggings.setTag_id(tag_id);
                    		taggings.setUrlMD5(urlMD5);
                    		taggings.setTaggable_type("OpenSourceProject");
                    		taggings.setContext("tags");
                    		taggings.setCreated_at(DateHandler.getNow());
                    		taggings.setDisagree_num(50);
                    		//将Taggings对象存入数据库中
                    		try {
                        		dbSource.insertTaggings(taggingsTableName, taggings);
                    		} catch (Exception e) {
                    			//在插入记录之前 gather_projects表中的记录已经被删除掉了
                    			System.out.println(e.getMessage());
                    			System.exit(0);
                    		}
                    	}
                    }
                } catch (Exception ex) {
                    // 数据迁移过程可能发生异常情况
                    logger.error(ex.toString());
                    System.exit(0);
                }

                // 更新执行结束时间
                gatherDao.updateTaskEndTime(conf.getMigrationTask(),sourceIdBegin, num,conf.getSourceTableName(),conf.getTargetTableName());
                logger.info("EndTime:" + new Date());

                // 更新游标到本次 EndId+1;
                dbSource.updatePointer(conf.getPointerTableName(), conf.getSourceTableName(), conf.getTargetTableName()
                        , sourceIdEnd + 1);//sourceIdBegin + idsIncrement
            }
        }
	}
	
	
	//处理URL不存在的项目 插入gather_projects表
	public void handleInsertGatherProjects(GatherProjectsModel model, Configure conf){
		gatherDao.moveDataInsert(conf.getTargetTableName(),conf.getTargetFields(), model);
//		int taggable_id = gatherDao.getAutoIncrementIdFromTable(conf.getTargetTableName(), model);
	}
	
	//处理URL相同的项目更新 id表示更新的项目固定id
	public void handleUpdateGatherProjects(int id, GatherProjectsModel model_new){
		//删除gather_projects表中原记录
//		dbSource.deleteItemById(gatherProjectsTableName, id);
//		List<EddRelations> eddRelationList = dbSource.getEddRelationsByGatherProjectsId(eddRelationTableName, id);
//		for(EddRelations relation:eddRelationList){
//			if(relation.getOsp_id() != null){
//				//删除osp_id对应的open_source_projects表中的记录
//				dbDest.deleteOpenSourceProjectsItem(openSourceProjectsTableName, relation.getOsp_id());
//			}
//			//删除edd_relations表中的记录
//			dbSource.deleteEddRelationsItem(eddRelationTableName, relation.getId());
//		}
//		//如果有剩余的关联 插入剩余的关联
//		String relation_new = ",";
//		Map<String, Integer> relationMap = getRelationMap(eddRelationList);
//		Set<String> keys = relationMap.keySet();
//		Iterator<String> it = keys.iterator();
//		while(it.hasNext()){
//			String key = it.next();
//			if(Integer.parseInt(key) != id)
//				relation_new = relation_new + key + ",";//如果是已经删除的id 就不添加到新的relation字符串中
//		}
//		if(relation_new.length() > 1){
//			//表示有剩余的关联需要插入edd_relations表中
//			EddRelations r = new EddRelations();
//			r.setGather_projects_ids(relation_new);
//			dbSource.insertEddRelations(eddRelationTableName, r);
//		}
//		
//		//在gather_projects表中插入新记录
//		gatherDao.moveDataInsert(conf.getTargetTableName(), conf.getTargetFields() , model_new);
//		int taggable_id = gatherDao.getAutoIncrementIdFromTable(conf.getTargetTableName(), model_new);
//		return taggable_id;
		
		gatherDao.moveDataUpdate(gatherProjectsTableName, model_new, id);//更新数据gather_projects表
		//更新维持更新表 update_control_projects
		//首先判断表前面有没有当前项目还没有再次更新的
		UpdateControlProjects sameUpdate = updateControlProjectsDao.findSameUpdate(updateControlProjectsTableName, id);
		if(sameUpdate == null){
			//表示没有相同的update 则直接插入
			updateControlProjectsDao.insertOneItem(updateControlProjectsTableName, id);
		}else{
			//表示有相同的更新请求 更新时间
			updateControlProjectsDao.updateItem(updateControlProjectsTableName, sameUpdate);
		}
		
	}
}
